from flask import request, jsonify
from aps import app

from aps.models.rol import *
from aps.models.permiso import *
from aps.models.rolpermiso import *

@app.route('/crear_permiso', methods=['GET', 'POST']) 
def crear_permiso():
    """
    Nos permite traer los formetros que fueron cargados por el usuario
    y guardarlos en la base de datos.
    @param  request: objeto que encapsula la peticion del cliente
    @return: True si la accion se realizo correctamente
    """ 
    nombre       = request.form['nombre']
    descripcion  = request.form['descripcion']
    codificacion = request.form['codificacion']
    # Se agrega a la BD
    model = Permiso(nombre,descripcion,codificacion)
    bdsession.add(model)  
    return jsonify ({'success':True})

@app.route('/modificar_permiso', methods=['GET', 'POST']) 
def modificar_permiso():
    """
    Nos permite traer los formetros que fueron modificados por el usuario
    y guardar los cambios en la base de datos.
    @param  request: objeto que encapsula la peticion del cliente
    @return: True si la accion se realizo correctamente
    """ 
    id           = request.form['id']
    nombre       = request.form['nombre']
    descripcion  = request.form['descripcion']
    accion       = request.form['accion']
    codificacion = request.form['codificacion']   # posible nueva accion
    if accion != codificacion:
        accion = codificacion
    # Se modifica en la BD
    model         = Permiso(nombre,descripcion,accion)
    model.id      = id
    bdsession.merge(model)   
    return jsonify ({'success':True})

@app.route('/eliminar_permiso', methods=['GET', 'POST']) 
def eliminar_permiso():
    """
    Nos permite traer el id del permiso a eliminar, eliminar las dependendcias
    del mismo con respecto a otras tablas y eliminar el registro de la base de datos.
    @param  request: objeto que encapsula la peticion del cliente
    @return: True si la accion se realizo correctamente y False en caso contrario
    """ 
    id      = request.form['id']
    permiso = bdsession.query(Permiso).filter_by(id=id).first()
    if permiso is None:
        return jsonify ({'success':False})
    bdsession.delete(permiso)
    return jsonify ({'success' : True})

@app.route('/consultar_permiso', methods=['GET', 'POST']) 
def consultar_permiso():
    """
    Nos permite traer los formetros de consulta(el filtro y el valor) y mostrar
    los permisos que cumplen con la condicion del filtro.
    @param  request: objeto que encapsula la peticion del cliente
    @return: si la accion se realizo correctamente
    """ 
    permisos = None
    if request.args.has_key('filtro'):
        filtro    = request.args['filtro']
        valor     = request.args['valor']
        sentencia = 'SELECT * from Permiso WHERE {0}=\'{1}\''.format(filtro,valor)
        permisos  = bdsession.query(Permiso).from_statement(sentencia).all()
    else:
        permisos = bdsession.query(Permiso).all()
    
    data = []
    for permiso in permisos:
        if permiso.nivel > 0:
            item = {}
            item['id'] = permiso.id
            item['nombre'] = permiso.nombre
            item['descripcion'] = permiso.descripcion
            item['accion'] = permiso.accion
            data.append(item)
    return jsonify ({'success':True, 'data':data, 'total':len(data)})

@app.route('/consulta_acciones', methods=['GET', 'POST']) 
def consulta_acciones():
    """
    Nos permite traer todas las acciones posibles que pueden realizarce con los permisos
    @param  request: objeto que encapsula la peticion del cliente
    @return: True si la accion se realizo correctamente, la cantidad de acciones y la lista de acciones
    """ 
    id_rol = request.form['idrol']
    rol    = bdsession.query(Rol).filter_by(id=id_rol).first()
    lista  = rol.permisos
    data = []
    for p in lista:
        item = {}
        item['permiso'] = p.permiso.accion
        item['nivel']   = p.permiso.nivel
        data.append(item)
    return jsonify ({'success':True, 'total':len(data), 'data':data})

@app.route('/consulta_asignar_permisos', methods=['GET', 'POST']) 
def consulta_asignar_permisos():
    """
    Nos permite traer todos los permisos asignados y asignables a un rol
    @param  request: objeto que encapsula la peticion del cliente
    @return: True si la accion se realizo correctamente, la lista de permisos asignados al rol y la lista de permisos asignables al rol
    """
    def process_permiso_list(list):
        """
        Serializa una lista de con los datos de los permisos para enviarla al cliente
        @param  list: lista de objectos Permiso obtenidas desde la BD
        @return: result lista procesada de permisos
        """
        result = []
        for permiso in list:
            if permiso.nivel > 0:
                item = [None,None,None,None]
                item[0] = permiso.id
                item[1] = permiso.nombre
                item[2] = permiso.descripcion
                item[3] = permiso.accion
                result.append(item)
        return result
    
    id_rol = request.form['id']
    # Obtenemos la lista de permisos que fueron asignados al rol
    # Permisos es de tipo RolPermiso[] por tanto es necesario extraer el 'permiso' de la relacion
    permisos_asignados = [x.permiso for x in bdsession.query(Rol).filter_by(id=id_rol).first().permisos]
    # Obtenemos la lista de permisos que no fueron asignados al rol
    permisos_asignables = bdsession.query(Permiso).from_statement('select * from Permiso where id not in (select idpermiso from RolPermiso where idrol=\'{0}\')'.format(id_rol)).all()
    
    asignados  = process_permiso_list(permisos_asignados)
    asignables = process_permiso_list(permisos_asignables)

    return jsonify ({'success':True, 'asignados':asignados, 'asignables':asignables})
    
@app.route('/asignar_desasignar_permiso', methods=['GET', 'POST']) 
def asignar_desasignar_permiso():
    """
    Nos permite asignar/desasignar permisos a un rol
    @param  request: objeto que encapsula la peticion del cliente
    @return: True si la accion se realizo correctamente
    """
    received   = eval(request.form['data'])
    # id del rol a asignar/desasignar roles
    id_rol = received['id_rol']
    # ids de permisos asignados
    data   = received['data']

    # obtenemos el rol desde la BD
    rol   = bdsession.query(Rol).filter_by(id=id_rol).first()
    # eliminamos sus permisos asignados anteriormente
    bdsession.query(RolPermiso).filter_by(idrol=id_rol).delete()
#     bdsession.commit()
    # actualizamos el rol
    bdsession.refresh(rol); 
#     bdsession.commit()
    # creamos una nueva lista de permisos asignados
    for id_permiso in data:
        rol.permisos.append(RolPermiso(id_rol, id_permiso))
    # guardamos los cambios
    bdsession.merge(rol)    
    
    return jsonify ({'success':True})

@app.route('/consulta_permiso_x_rol', methods=['GET', 'POST']) 
def consulta_permiso_x_rol():
    """
    Nos permite obtener la lista detallada de permisos asignados a un rol
    @param  request: objeto que encapsula la peticion del cliente
    @return: True si la accion se realizo correctamente
    """
    id_rol = request.args['id_rol']
    rol    = bdsession.query(Rol).filter_by(id=id_rol).first()
    data = []
    for permiso in rol.permisos:
        item = {}
        item['id'] = permiso.permiso.id
        item['nombre'] = permiso.permiso.nombre
        item['descripcion'] = permiso.permiso.descripcion
        item['accion'] = permiso.permiso.accion
        data.append(item)
    return jsonify ({'success':True, 'data':data, 'total':len(data)})
